package algorithm;

import schedule.Schedule;
import afsjava.Tjob;

public class DynamicRules {
	
private static double setPbar (Tjob[] jobArray, int[] scheduledJobs){
		
		double sumaTiempos =0;
		double pbar;
		int numberOfRemainingJobs=0;
		
		for (int j = 0; j < Tjob.getNumberOfJobs(); j++){
			
			if (scheduledJobs[j] == 0){
				
				sumaTiempos = sumaTiempos + jobArray[j].getProcessTime(0);
				numberOfRemainingJobs ++;
			}
		}
		
		pbar = sumaTiempos / numberOfRemainingJobs;

		return pbar;
		
	}  

/**
* @param jobArray: Array of jobs
* @param schedule: Resulting Schedule
* @param kConstant Scaling parameter
*/
public void ruleATC (Tjob[] jobArray, double kConstant, Schedule schedule){
	
	double ij[] = new double[Tjob.getNumberOfJobs()]; //indices array
	int t = 0; // initial time
	int slack; // slack max (dj-pj-t,0) dj is the due date, pj is the process time
	double pbar; //average process time
	double maxIj =0;
	int pos=0; // position in the array Ij
	int minStartTime =0;
	
	try {
	// scheduledJobs[j] = 1 if job already scheduled, 0 otherwise
		int scheduledJobs[] = new int [Tjob.getNumberOfJobs()];
		
		for (int i=0; i < Tjob.getNumberOfJobs(); i++){
			
			pbar = setPbar(jobArray, scheduledJobs);
			maxIj = -1;
			pos = 0;
			
			for (int j=0; j < Tjob.getNumberOfJobs(); j++){
					
				if (scheduledJobs[j] == 0){
					
					int wj = jobArray[j].getWeight();
					int pj = jobArray[j].getProcessTime(0);
					int dj = jobArray[j].getDue();
					int rj = jobArray[j].getRelease();
					
					if (rj > t)
						minStartTime = rj;
					else
						minStartTime = t;
					
					slack = dj- pj - minStartTime;
					if (slack < 0){
						slack = 0;
					}
	
					ij[j] = wj* Math.exp(-slack/(kConstant*pbar))/pj;
					if (ij[j] > maxIj) {
						maxIj = ij[j];
						pos = j;					
					}
							
				}
				else {					
					ij[j] = -1;				
				}	
			}// for j
			
			schedule.addToSchedule(pos, 0, 0);
			if (t < jobArray[pos].getRelease()){
				t = jobArray[pos].getRelease();
			}
				t = t + jobArray[pos].getProcessTime(0);
			
				
			scheduledJobs[pos]=1;
		
		}// for i
	}
	catch (Exception e){
		System.out.println("Error in  ATC rule");
	}

}

}
